package logic

import (
	"fmt"

	"nhooyr.io/websocket"
)

type broadcaster struct {
	// 所有聊天室用户
	users map[string]*User
	// 所有 channel 统一管理，可以避免外部乱用

	enteringChannel chan *User
	leavingChannel  chan *User
	messageChannel  chan string

	// 判断该昵称用户是否可进入聊天室（重复与否）：true 能，false 不能
	checkUserChannel      chan string
	checkUserCanInChannel chan bool
}

func (b *broadcaster) Start() {
	for {
		select {
		case user := <-b.enteringChannel:
			// 新用户进入
			b.users[user.Username] = user
		case user := <-b.leavingChannel:
			// 用户离开
			delete(b.users, user.Username)
			// 避免 goroutine 泄露
			user.CloseMessageChannel()
		case msg := <-b.messageChannel:
			// 给所有在线用户发送消息
			fmt.Println("msg", msg)
			for _, user := range b.users {
				user.MessageChannel <- msg
			}
		case nickname := <-b.checkUserChannel:
			//判断用户是否存在
			fmt.Printf("判断用户是否存在")
			if _, ok := b.users[nickname]; ok {
				b.checkUserCanInChannel <- false
			} else {
				b.checkUserCanInChannel <- true
			}
		}
	}
}

func (b *broadcaster) UserEntering(u *User) {
	b.enteringChannel <- u
}

func (b *broadcaster) UserLeaving(u *User) {
	b.leavingChannel <- u
}

func (b *broadcaster) Broadcast(u *User, msg string) {
	sendMsg := u.Username + ":" + msg
	b.messageChannel <- sendMsg
}

func (b *broadcaster) CanEnterRoom(nickname string) bool {
	b.checkUserChannel <- nickname
	return <-b.checkUserCanInChannel
}

// 增加用户
func (b *broadcaster) AddUser(conn *websocket.Conn, username string) *User {
	user := NewUser(conn, username)
	Broadcaster.users[user.Username] = user
	fmt.Println("user add successfully")
	return user
}

// 用户退出
func (b *broadcaster) DeleteUser(username string) {
	Broadcaster.users[username] = nil
	fmt.Println("user delete successfully")
}

// 饿汉式单例模式
var Broadcaster = &broadcaster{
	users: make(map[string]*User),

	enteringChannel: make(chan *User),
	leavingChannel:  make(chan *User),
	messageChannel:  make(chan string),

	checkUserChannel:      make(chan string),
	checkUserCanInChannel: make(chan bool),
}
